#ifndef FUNCTION
#define FUNCTION
#include <iostream>
#include <map>
#include "../../base/TemplateParser/Parser.h"
using namespace std;
class Function:public Parser
{
	public:
		string parseFunction(string);
		bool isFunction(string);
		virtual string parse(string)=0;
	private:
		string convertString(string);
		string convertInt(string);
		string convertBool(string);
		string count(string);
		string isArray(string);
 };

string Function::parseFunction(string in){
	string fnname;
	string param;
	//get fnname and param
	string::iterator it=in.begin()+1;
	string::size_type pos=1;
	while(it!=in.end()){
		if(*it=='('){
			fnname=in.substr(0,pos);
			pos++;
			param=in.substr(pos,in.size()-pos-1);
			break;
		}
		it++;
		pos++;
	}
	if(param!=""){
		if(isOperation(param))param=parseOperation(param);
		else if(isFunction(param))param=parseFunction(param);
	}

	if(fnname=="string")return convertString(param);
	if(fnname=="int")return convertInt(param);
	if(fnname=="bool")return convertBool(param);
	if(fnname=="count")return count(param);
	if(fnname=="isArray")return isArray(param);
	return "";
}
bool Function::isFunction(string dir){
	dir=getDirection(dir);
	return dir=="int"
			|| dir=="string"
			|| dir=="echo"
			|| dir=="count"
			|| dir=="bool"
			|| dir =="count"
			|| dir=="isArray"
			;
}

string Function::count(string in){
	map<string,boost::any> arr;
	try {
		arr=boost::any_cast<map<string,boost::any> >(getViewAnyData(in));
		return StringProcessor::itoa(arr.size()) ;
	}
	catch(...){
		return "0";
	}
	return "0";
}

string Function::isArray(string in){
	try {
		boost::any_cast<map<string,boost::any> >(getViewAnyData(in));
		return "true";
	}
	catch(...){
		try {
			boost::any_cast<vector<boost::any> >(getViewAnyData(in));
					return "true";
		}
		catch(...){

		}
	}
	return "false";
}

string Function::convertInt(string in){
	//check string
	if(in.size()>0 && in.at(0)=='"' && in.at(in.size()-1)=='"')in=in.substr(1,in.size()-2);
	//check Operation
	else{
		in=parseOperation(in);
	}
	return StringProcessor::itoa(StringProcessor::atoi(in));
}

string Function::convertString(string in){
	//check string
	if(in.size()>0 && in.at(0)=='"' && in.at(in.size()-1)=='"')return in;
	//check Operation
	else{
		in=parseOperation(in);
		//to string:
		in="\"" + in + "\"";
	}
	return in;
}

string Function::convertBool(string in){
	if(in=="true"||in!=""&&in!="0"&&in!="false")return "true";
	return "false";
}



#endif
